package cn.south.campus.business.service.impl;

import cn.south.campus.business.mapper.AddressMapper;
import cn.south.campus.business.model.bo.LoginContext;
import cn.south.campus.business.model.bo.LoginInfo;
import cn.south.campus.business.model.entity.Address;
import cn.south.campus.business.model.vo.AddressVo;
import cn.south.campus.business.service.AddressService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 地址表 服务实现类
 * </p>
 *
 * @author chow
 * @since 2024-11-14
 */
@Service
@AllArgsConstructor
public class AddressServiceImpl extends ServiceImpl<AddressMapper, Address> implements AddressService {

    private final AddressMapper addressMapper;

    @Override
    public List<AddressVo> listAddress() {
        LoginInfo loginInfo = LoginContext.getContext();
        LambdaQueryWrapper<Address> wrapper = new LambdaQueryWrapper<Address>()
                .eq(Address::getUserId, loginInfo.getId())
                .orderByDesc(Address::getIsDefault)
                .orderByDesc(Address::getCreateTime);
        List<Address> addressList = addressMapper.selectList(wrapper);
        return addressList.stream().map(AddressVo::convert).collect(Collectors.toList());
    }

    @Override
    public void addAddress(AddressVo addressVo) {
        LoginInfo loginInfo = LoginContext.getContext();
        Address address = new Address();
        address.setUserId(loginInfo.getId());
        address.setName(addressVo.getName());
        address.setPhone(addressVo.getPhone());
        address.setBuilding(addressVo.getBuilding());
        address.setAddress(addressVo.getAddress());
        address.setIsDefault(addressVo.getIsDefault());
        addressMapper.insert(address);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void defaultAddr(Long id) {
        LoginInfo loginInfo = LoginContext.getContext();
        LambdaQueryWrapper<Address> wrapper = new LambdaQueryWrapper<Address>()
                .eq(Address::getUserId, loginInfo.getId())
                        .eq(Address::getIsDefault, 1);
        Address address = addressMapper.selectOne(wrapper);
        if (address != null) {
            address.setIsDefault(0);
            addressMapper.updateById(address);
        }
        address = addressMapper.selectById(id);
        if (address != null) {
            address.setIsDefault(1);
            addressMapper.updateById(address);
        }
    }

    @Override
    public AddressVo getAddressById(Long id) {
        LoginInfo loginInfo = LoginContext.getContext();
        LambdaQueryWrapper<Address> wrapper = new LambdaQueryWrapper<Address>()
                .eq(Address::getUserId, loginInfo.getId())
                .eq(Address::getId, id);
        return AddressVo.convert(addressMapper.selectOne(wrapper));
    }

    @Override
    public AddressVo getDefaultAddress() {
        LoginInfo loginInfo = LoginContext.getContext();
        LambdaQueryWrapper<Address> wrapper = new LambdaQueryWrapper<Address>()
                .eq(Address::getUserId, loginInfo.getId())
                .eq(Address::getIsDefault, 1);
        Address address = addressMapper.selectOne(wrapper);
        if (address != null) {
            return AddressVo.convert(address);
        }
        wrapper = new LambdaQueryWrapper<Address>()
                .eq(Address::getUserId, loginInfo.getId())
                .orderByDesc(Address::getUpdateTime).last("limit 1");
        address = addressMapper.selectOne(wrapper);
        return AddressVo.convert(address);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateAddress(AddressVo addressVo) {
        Address address = AddressVo.convert(addressVo);
        if (address.getIsDefault() == 1) {
            LoginInfo loginInfo = LoginContext.getContext();
            LambdaQueryWrapper<Address> wrapper = new LambdaQueryWrapper<Address>()
                    .eq(Address::getUserId, loginInfo.getId())
                    .eq(Address::getIsDefault, 1);
            Address defAdd = addressMapper.selectOne(wrapper);
            if (!defAdd.getId().equals(address.getId())) {
                defAdd.setIsDefault(0);
                addressMapper.updateById(defAdd);
            }
        }
        addressMapper.updateById(address);
    }
}
